﻿namespace PugLib.Net
{
    using System;
    using System.IO;
    using System.Net;

    /// <summary>
    /// If necessary, gets the latest version of a file from a web server
    /// </summary>
    public class LatestFileVersionDownloader
    {
        private readonly Uri _remoteFile;
        private readonly Uri _localFile;

        /// <summary>
        /// Gets the latest version of the remoteFile, stores it to 
        /// </summary>
        /// <param name="remoteFile">full Uri to remote file</param>
        /// <param name="localFile">local path to store the download</param>
        public LatestFileVersionDownloader(Uri remoteFile, Uri localFile)
        {
            _remoteFile = remoteFile;
            _localFile = localFile;
        }

        /// <summary>
        /// The local location of the document
        /// </summary>
        public string LocalFilePath
        {
            get { return _localFile.AbsolutePath; }
        }

        /// <summary>
        /// Gets latest file from the web if necessary.
        /// </summary>
        public void EnsureLatestVersionOnDisk()
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_remoteFile);
            FileInfo fi = new FileInfo(LocalFilePath);
            if (fi.Exists)
            {
                request.IfModifiedSince = fi.CreationTimeUtc;
            }
            try
            {
                using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
                using (Stream stream = resp.GetResponseStream())
                using (Stream file = File.Create(LocalFilePath))
                {
                    Byte[] buffer = new Byte[65536];
                    for (Int32 read = stream.Read(buffer, 0, buffer.Length);
                         read != 0;
                         read = stream.Read(buffer, 0, buffer.Length))
                    {
                        file.Write(buffer, 0, read);
                    }
                }
            }
            catch (WebException ex)
            {
                if (((HttpWebResponse)ex.Response).StatusCode != HttpStatusCode.NotModified)
                {
                    throw;
                }
            }
        }
    }
}